package com.example.qytw.qytw;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import lombok.Getter;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;


/**
 * -----------------------------
 * PackageName： com.example.qytw.qytw
 * ClassName：DemoDataListener
 * Description：
 *
 * @author：it-yml CreateTime：2024-09-29
 * -----------------------------
 */
@Service
public class DemoDataListener extends AnalysisEventListener<ExcelMode> {
    List<ExcelModeOut> list = new CopyOnWriteArrayList<>();
    List<ExcelModeOut> errorList = new CopyOnWriteArrayList<>();
    ExecutorService executor = new ThreadPoolExecutor(
            5, // 核心线程数
            5, // 最大线程数
            60, // 空闲线程存活时间
            TimeUnit.SECONDS, // 时间单位
            new LinkedBlockingQueue<Runnable>() // 任务队列
    );

    public static GenerationResult callWithMessage(String con) throws ApiException, NoApiKeyException, InputRequiredException {
        Generation gen = new Generation();
        Constants.apiKey = "sk-a6e5cfa835e34afa8332399710f5bb9d";//这里
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content("You are a helpful assistant.")
                .build();
        //并且生成mysql 插入语句
        String hua = "分析下面西班牙语内容判断出属于信用贷款的哪个场景，并将输出场景(c1)和借贷场景有关的关键词(原文)(c2)和整句话的翻译(c3)。同时输出公司名字(c4)，不输出除敏感信息,如合同编号等，只输出json 结果";
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content(hua + "\n" + con)
                .build();
        GenerationParam param = GenerationParam.builder()
                .model("qwen-plus")
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
        return gen.call(param);
    }


    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(ExcelMode data, AnalysisContext context) {
        executor.execute(()->{
            String column1 = data.getColumn1();
            ExcelModeOut excelModeOut = new ExcelModeOut();
            excelModeOut.set原文(column1);
            try {
                GenerationResult result = callWithMessage(column1);
                String content = result.getOutput().getChoices().get(0).getMessage().getContent();
                String[] split = content.split("```");
                String replace = split[1].replace("```", "").replace("json", "");
                try {
                    JSONObject jsonObject = JSONObject.parseObject(replace);
                    System.out.println(column1);
                    System.out.println(replace);
                    excelModeOut.set翻译(jsonObject.get("c3").toString());
                    excelModeOut.set短信场景(jsonObject.get("c1").toString());
                    String[] c2s = jsonObject.get("c2").toString().split(",");
                    String c2sc = "xxx_Columns like '%";
                    for (int i = 0; i < c2s.length; i++) {
                        c2sc = c2sc +  c2s[i].trim() +"%' and xxx_Columns like '%";
                    }
                    c2sc = c2sc +  jsonObject.get("c4").toString()+ "%'";
                    String c2scs = c2sc.replace("[", "").replace("]", "").replaceAll("\\d+","");
                    excelModeOut.set模糊匹配(c2scs);
                    list.add(excelModeOut);
                } catch (Exception e) {
                    excelModeOut.set解析失败(content);
                    errorList.add(excelModeOut);
                }


            } catch (ApiException | NoApiKeyException | InputRequiredException e) {
                // 使用日志框架记录异常信息
                System.err.println("An error occurred while calling the generation service: " + e.getMessage());
                excelModeOut.set解析失败("网络异常");
                errorList.add(excelModeOut);
            }

        });
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        shutdownTp();
        writeFile(context);

        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
    }

    private void writeFile(AnalysisContext context) {
        String fileName = context.readWorkbookHolder().getFile().getName();
        String returnAbsolutePath = context.readWorkbookHolder().getFile().getAbsolutePath();

        if(list.size()>0){
            String finallyPath = returnAbsolutePath.replace(fileName, "output/");
            Path path = Paths.get(finallyPath);
            try {
                if(!path.toFile().isDirectory()){
                    Files.createDirectory(path);
                }
            } catch (IOException e) {
                System.out.println("文件夹以存在");
            }
            EasyExcel.write(finallyPath+"finally-"+fileName, ExcelModeOut.class).sheet(fileName).doWrite(list);
        }
        if(errorList.size()>0){
            String errorFinallyPath = returnAbsolutePath.replace(fileName, "error-output/");
            Path errorPath = Paths.get(errorFinallyPath);
            try {
                if(!errorPath.toFile().isDirectory()){
                    Files.createDirectory(errorPath);
                }
            } catch (IOException e) {
                System.out.println("文件夹以存在");
            }

            EasyExcel.write(errorFinallyPath+"error-finally-"+fileName, ExcelModeOut.class).sheet(fileName).doWrite(errorList);
        }
    }

    private void shutdownTp() {
        // 关闭线程池，不再接受新任务
        executor.shutdown(); // Disable new tasks from being submitted

        try {
            // 等待所有已提交的任务完成
            if (!executor.awaitTermination(6000, TimeUnit.SECONDS)) {
                System.err.println("线程池没有在指定时间内终止");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            executor.shutdownNow();
            Thread.currentThread().interrupt(); // Preserve interrupt status
        } finally {
            // 如果等待超时或被中断，强制关闭所有活动任务
            if (!executor.isTerminated()) {
                executor.shutdownNow(); // Cancel currently executing tasks
            }
        }
    }
}
